<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
  <link rel="stylesheet" href="http://github.com/jquery/qunit/raw/master/qunit/qunit.css" type="text/css" media="screen" />
  <script type="text/javascript" src="http://github.com/jquery/qunit/raw/master/qunit/qunit.js"></script>
  <script>

// Mocking Jetpack container
var jetpack = {};
jetpack.statusBar = {};
jetpack.statusBar.append = function(code) {
    jetpack.widget = code;
};

  </script>
  <script type="text/javascript" src="http://uniquepasswordbuilder.googlecode.com/svn/trunk/uniquepasswordbuilder-jetpack.js"></script>
  <script>

$(document).ready(function(){

module("JetPack Widget"); 

test("jetpack widget has been included", function() {
  ok( jetpack.widget, "Jetpack is here" );
});


module("Sha1");

test("Sha1 has been loaded", function() {
  var sha1 = new Sha1();
  ok( sha1, "Sha1 is present" );
});

test("Sha1.sha1Hash() produces correct hashes", function() {
  var sha1 = new Sha1();
  equals( 'a9993e364706816aba3e25717850c26c9cd0d89d', sha1.sha1Hash('abc'));
  ok( sha1.sha1Hash('abc') != sha1.sha1Hash('abcd'));
});


module("Unique Password Builder");

test("UniquePasswordBuilder has been loaded", function() {
  var uniquePasswordBuilder = new UniquePasswordBuilder(null, null);
  ok( uniquePasswordBuilder, "UniquePasswordBuilder is present" );
});

test("UniquePasswordBuilder.makeHashHumanReadable produces simple passwords", function() {
  var sha1 = new Sha1();
  var uniquePasswordBuilder = new UniquePasswordBuilder(jetpack.widget, sha1);
  uniquePasswordBuilder.setComplex(false);
  
  var password1 = uniquePasswordBuilder.makeHashHumanReadable(sha1.sha1Hash('abc'));
  ok( password1, "Password 1 has been generated" );
  ok( password1.length == 10, "Password 1 has correct length" );

  var password2 = uniquePasswordBuilder.makeHashHumanReadable(sha1.sha1Hash('abcd'));
  ok( password2, "Password 2 has been generated" );
  ok( password2.length == 10, "Password 2 has correct length" );
  ok( password1 != password2, "Password 1 is different than password 2" );
});

test("UniquePasswordBuilder.makeHashHumanReadable produces complex passwords", function() {
  var sha1 = new Sha1();
  var uniquePasswordBuilder = new UniquePasswordBuilder(jetpack.widget, sha1);
  uniquePasswordBuilder.setComplex(true);
  
  var password1 = uniquePasswordBuilder.makeHashHumanReadable(sha1.sha1Hash('abc'));
  ok( password1, "Password 1 has been generated" );
  ok( password1.length == 10, "Password 1 has correct length" );

  var password2 = uniquePasswordBuilder.makeHashHumanReadable(sha1.sha1Hash('abcd'));
  ok( password2, "Password 2 has been generated" );
  ok( password2.length == 10, "Password 2 has correct length" );
  ok( password1 != password2, "Password 1 is different than password 2" );  
});

test("UniquePasswordBuilder.makeHashHumanReadable producing 100 simple passwords are valids", function() {
  var sha1 = new Sha1();
  var uniquePasswordBuilder = new UniquePasswordBuilder(jetpack.widget, sha1);
  uniquePasswordBuilder.setComplex(false);
    
  for (var i = 0; i < 100; i++) {
    var password = uniquePasswordBuilder.makeHashHumanReadable(sha1.sha1Hash('abc' + i));
    ok( areThesesCharactersValidForASimplePassword(password), "Password [" + password + "] is valid" );
  }
});

test("UniquePasswordBuilder.makeHashHumanReadable contains all expexted simple characters", function() {
    for(var i = 48; i <= 57; i++) // From 0 to 9
        ok( characterMapForSimplePassword[String.fromCharCode(i)], "Map contains " + characterMapForSimplePassword[String.fromCharCode(i)] + " signs {" + String.fromCharCode(i) + "}" );

    for(var i = 65; i <= 90; i++) // From A to Z
        ok( characterMapForSimplePassword[String.fromCharCode(i)], "Map contains " + characterMapForSimplePassword[String.fromCharCode(i)] + " signs {" + String.fromCharCode(i) + "}" );

    for(var i = 97; i <= 122; i++) // From a to z
        ok( characterMapForSimplePassword[String.fromCharCode(i)], "Map contains " + characterMapForSimplePassword[String.fromCharCode(i)] + " signs {" + String.fromCharCode(i) + "}" );
});

test("UniquePasswordBuilder.makeHashHumanReadable producing 100 complex passwords are valids", function() {
  var sha1 = new Sha1();
  var uniquePasswordBuilder = new UniquePasswordBuilder(jetpack.widget, sha1);
  uniquePasswordBuilder.setComplex(true);
  
  for (var i = 0; i < 100; i++) {
    var password = uniquePasswordBuilder.makeHashHumanReadable(sha1.sha1Hash('abc' + i));
    ok( areThesesCharactersValidForAComplexPassword(password), "Password [" + password.replace('<','&lt;').replace('>','&gt;') + "] is valid" );
  }  
});

test("UniquePasswordBuilder.makeHashHumanReadable contains all expexted complex characters", function() {
    for(var i = 33; i <= 126; i++) // From 0 to 9
        ok( characterMapForComplexPassword[String.fromCharCode(i)], "Map contains " + characterMapForComplexPassword[String.fromCharCode(i)] + " signs {" + String.fromCharCode(i) + "}" );
});


});

  </script>
  <script>

/*
 * Testing helpers methods and 2 global maps, used in test
 */
var characterMapForSimplePassword = {}; // Map wich will store, for each character for simples passwords, the number of occurences

function areThesesCharactersValidForASimplePassword(value) {
    for(i = 0; i <value.length; i++) {
        var charCode = value.charCodeAt(i);
        var isNum = charCode >= 48 && charCode <= 57; // Numbers
        var isAlphaUpperCase = charCode >= 65 && charCode <= 90; // From A to Z
        var isAlphaLowerCase = charCode >= 67 && charCode <= 122; // From a to z
        
        var character = value.charAt(i); 
        if (!characterMapForSimplePassword[character]) // If first entry
            characterMapForSimplePassword[character] = 0;
        characterMapForSimplePassword[character]++; // Incrementing the number of occurence for that character in a map
        
        if (!isNum && !isAlphaUpperCase && !isAlphaLowerCase)
            return false;
    }
    return true;
}

var characterMapForComplexPassword = {}; // Map wich will store, for each character for complex passwords, the number of occurences

function areThesesCharactersValidForAComplexPassword(value) {
    for(i = 0; i <value.length; i++) {
        var charCode = value.charCodeAt(i);
        
        var character = value.charAt(i); // If first entry
        if (!characterMapForComplexPassword[character])
            characterMapForComplexPassword[character] = 0;
        characterMapForComplexPassword[character]++; // Incrementing the number of occurence for that character in a map

        if (charCode < 33 || charCode > 126) // If the character is out of printable character
            return false;
    }
    return true;
}

  </script>

</head>
<body>
  <h1 id="qunit-header">QUnit example</h1>
 <h2 id="qunit-banner"></h2>
 <h2 id="qunit-userAgent"></h2>
 <ol id="qunit-tests"></ol>
</body>
</html>
